package com.webbyit.swing;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextLayout;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * A class to demo using Java2D to create on the fly icons
 *
 * @author webbst
 */
public class DynamicIcon {

    private DynamicIcon() {
    }

    public static BufferedImage getMarkerIcon(char character, int dimension, Color bg, Color fg) {
        return getMarkerIcon(Character.toString(character), dimension, bg, fg);
    }

    public static BufferedImage getMarkerIcon(String text, int dimension, Color bg, Color fg) {
        return getMarkerIcon(text, dimension, bg, fg, Color.BLACK);
    }

    public static BufferedImage getMarkerIcon(String text, int dimension, Color bg, Color fg, Color outline) {

        // new RGB image with transparency channel
        BufferedImage image = new BufferedImage(dimension, dimension, BufferedImage.TYPE_INT_ARGB);

        // create new graphics and set anti-aliasing hint
        Graphics2D graphics = (Graphics2D) image.getGraphics().create();
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        // Set fill color
        graphics.setColor(bg);
        graphics.fillOval(0, 0, dimension - 1, dimension - 1);

        // create spot in the upper-left corner using temporary graphics
        // with clip set to the icon outline
        GradientPaint spot = new GradientPaint(0, 0, new Color(255, 255, 255, 0), dimension,
                dimension, new Color(255, 255, 255, 0));
        Graphics2D tempGraphics = (Graphics2D) graphics.create();
        tempGraphics.setPaint(spot);
        tempGraphics.setClip(new Ellipse2D.Double(0, 0, dimension - 1, dimension - 1));
        tempGraphics.fillRect(0, 0, dimension, dimension);
        tempGraphics.dispose();

        // draw outline of the icon
        graphics.setColor(outline);
        graphics.drawOval(0, 0, dimension - 1, dimension - 1);

        // Draw the character
        graphics.setFont(new Font("Arial", Font.BOLD, (dimension / text.length())));
        Font font = new Font("Arial", Font.BOLD, (dimension / text.length()));
        FontRenderContext frc = graphics.getFontRenderContext();
        GlyphVector glyphVector = font.createGlyphVector(frc, text);
        float x = (float) (dimension - (float) glyphVector.getLogicalBounds().getWidth()) / 2;

        TextLayout mLayout = new TextLayout(text, graphics.getFont(), frc);
        float y = dimension - (float) ((dimension - mLayout.getBounds().getHeight()) / 2) - 1;

        graphics.setColor(fg);
        graphics.drawString(text, x, y);

        graphics.dispose();
        return image;

    }

    public static BufferedImage getSquareMarkerIcon(String text, final Font font, Color bg, Color fg, Color outline) {

        // Dummy image
        BufferedImage img = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);

        Graphics2D g = (Graphics2D) img.getGraphics().create();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        g.setFont(font);

        FontMetrics fm = g.getFontMetrics();
        Rectangle2D r2d = fm.getStringBounds(text, g);
        Rectangle rect = r2d.getBounds();

        // Ok now we know the size required lets start creating an image
        g.dispose();
        img = null;

        img = new BufferedImage(rect.width + 2, rect.height + 2, BufferedImage.TYPE_INT_ARGB);
        g = (Graphics2D) img.getGraphics().create();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g.setFont(font);
        g.setColor(bg);
        g.fillRoundRect(0, 0, img.getWidth(), img.getHeight(), 10, 10);

        // draw outline of the icon
        if (outline != null) {
            g.setColor(outline);
            g.drawRoundRect(0, 0, img.getWidth(), img.getHeight(), 10, 10);
        }
        // Draw the text
        g.setColor(fg);
        g.drawString(text, 1, img.getHeight() - fm.getDescent() - 1);

        g.dispose();
        return img;
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                final JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                final JPanel panel = new JPanel();
                panel.add(new JLabel(new ImageIcon(DynamicIcon.getMarkerIcon('x', 16, Color.GREEN, Color.BLACK))));
                panel.add(new JLabel(new ImageIcon(DynamicIcon.getMarkerIcon('x', 16, Color.BLUE, Color.WHITE))));
                panel.add(new JLabel(new ImageIcon(DynamicIcon.getMarkerIcon("87", 24, Color.GREEN, Color.BLACK))));
                panel.add(new JLabel(new ImageIcon(DynamicIcon.getMarkerIcon("92", 24, Color.BLUE, Color.WHITE))));
                panel.add(new JLabel(new ImageIcon(DynamicIcon.getMarkerIcon("E", 72, Color.BLUE, Color.WHITE))));
                panel.add(new JLabel(new ImageIcon(DynamicIcon.getMarkerIcon("72", 72, Color.BLUE, Color.WHITE))));
                JLabel lab = new JLabel();

                Font font = lab.getFont();//new Font("Arial", Font.BOLD, 9);
                panel.add(new JLabel(new ImageIcon(DynamicIcon.getSquareMarkerIcon("Hello", font, Color.green,
                        Color.black,
                        null))));
                frame.getContentPane().add(panel);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
